/**
* @Author: qinhaoda
* @Description:
* @File: manual
* @Version: 1.0.0
* @Date: 2023/3/1 18:42
 */
package discovery

import (
	"encoding/json"
	"fmt"
	"github.com/didi/nightingale/src/models"
	"github.com/didi/nightingale/src/modules/monapi/discovery"
)

func init() {
	discovery.DiscoveryRegister(&ManualDiscovery{})
}

type ManualDiscovery struct{}

func (m ManualDiscovery) Name() string                   { return "manual" }
func (m ManualDiscovery) Template() (interface{}, error) { return nil, nil }

func (m ManualDiscovery) Get(id int64) (interface{}, error) {
	row := new(models.ManualDiscovery)
	has, err := models.DB["mon"].Where("id = ?", id).Get(row)
	if !has {
		return nil, err
	}
	return row, err
}

func (m ManualDiscovery) Gets(nids []int64) (ret []interface{}, err error) {
	rows := []models.ManualDiscovery{}
	if len(nids) == 0 {
		err = models.DB["mon"].Find(&rows)
	} else {
		err = models.DB["mon"].In("nid", nids).Find(&rows)
	}
	for _, c := range rows {
		ret = append(ret, c)
	}
	return ret, err
}

func (m ManualDiscovery) GetByNameAndNid(name string, nid int64) (interface{}, error) {
	row := new(models.ManualDiscovery)
	has, err := models.DB["mon"].Where("name = ? and nid = ?", name, nid).Get(row)
	if !has {
		return nil, err
	}
	return row, err
}

func (m ManualDiscovery) GetsUnCorrelate(nids []int64) (ret []interface{}, err error) {
	rows := []models.ManualDiscovery{}
	err = models.DB["mon"].In("nid", nids).Where("service_id=0").Find(&rows)
	for _, c := range rows {
		ret = append(ret, c)
	}
	return ret, err
}

func (m ManualDiscovery) Create(data []byte, username string) error {
	row := new(models.ManualDiscovery)

	err := json.Unmarshal(data, row)
	if err != nil {
		return fmt.Errorf("unmarshal body %s err:%v", string(data), err)
	}

	can, err := models.UsernameCandoNodeOp(username, "mon_discovery_create", row.Nid)
	if err != nil {
		return err
	}
	if !can {
		return fmt.Errorf("permission deny")
	}

	row.Creator = username
	row.LastUpdator = username

	nid := row.Nid
	name := row.Name

	old, err := m.GetByNameAndNid(name, nid)
	if err != nil {
		return err
	}
	if old != nil {
		return fmt.Errorf("同节点下策略名称 %s 已存在", name)
	}
	return models.CreateDiscovery(m.Name(), username, row, false)
}

func (m ManualDiscovery) Update(data []byte, username string) error {
	row := new(models.ManualDiscovery)

	err := json.Unmarshal(data, row)
	if err != nil {
		return fmt.Errorf("unmarshal body %s err:%v", string(data), err)
	}

	can, err := models.UsernameCandoNodeOp(username, "mon_discovery_modify", row.Nid)
	if err != nil {
		return err
	}
	if !can {
		return fmt.Errorf("permission deny")
	}

	nid := row.Nid
	name := row.Name

	//校验采集是否存在
	obj, err := m.Get(row.Id) //id找不到的情况
	if err != nil {
		return fmt.Errorf("采集不存在 type:%s id:%d", m.Name(), row.Id)
	}

	tmpId := obj.(*models.ManualDiscovery).Id
	if tmpId == 0 {
		return fmt.Errorf("采集不存在 type:%s id:%d", m.Name(), row.Id)
	}

	row.LastUpdator = username

	old, err := m.GetByNameAndNid(name, nid)
	if err != nil {
		return err
	}
	if old != nil && tmpId != old.(*models.ManualDiscovery).Id {
		return fmt.Errorf("同节点下策略名称 %s 已存在", name)
	}

	return row.Update()
}

func (m ManualDiscovery) Delete(id int64, username string) error {
	tmp, err := m.Get(id) //id找不到的情况
	if err != nil {
		return fmt.Errorf("采集不存在 type:%s id:%d", m.Name(), id)
	}
	nid := tmp.(*models.ManualDiscovery).Nid
	can, err := models.UsernameCandoNodeOp(username, "mon_discovery_delete", int64(nid))
	if err != nil {
		return err
	}
	if !can {
		return fmt.Errorf("permission deny")
	}

	return models.DeleteDiscoveryById(m.Name(), username, id)
}
